#include "httpclient.h"
#include "curl/curl.h"
#include "ftcsettings.h"
#include <filesystem>
#include <fstream>
#include <string>
#include <QDebug>

// 静态初始化curl
static struct CurlInitializer_Ftc
{
	CurlInitializer_Ftc()
	{
		// 初始化curl
		curl_global_init(CURL_GLOBAL_DEFAULT);
	}

	~CurlInitializer_Ftc()
	{
		// 清理curl
		curl_global_cleanup();
	}
} curlInitializer_Ftc;

cxi_ftc::HttpClient::HttpClient(QString url)
	: m_url(std::move(url)), m_httpCode(0)
{
}
cxi_ftc::HttpClient::~HttpClient() = default;
long cxi_ftc::HttpClient::httpCode() const
{
	return m_httpCode;
}
QString cxi_ftc::HttpClient::error() const
{
	return m_error;
}
bool cxi_ftc::HttpClient::post(const std::string& requestData, std::string& responseData)
{
	responseData.clear();

	if (m_url.isEmpty())
	{
		m_error = "未指定请求HTTP(S)地址。";
		return false;
	}

	// 创建curl句柄
	CURL* curl = curl_easy_init();
	if (!curl)
	{
		m_error = "创建curl句柄失败。";
		return false;
	}

	// 设置URL
	curl_easy_setopt(curl, CURLOPT_URL, m_url.toStdString().c_str());

	if (!requestData.empty())
	{
		// 设置POST数据
		curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestData.c_str());
		curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, requestData.length());
	}
	else
	{
		curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
	}

	// 设置写数据回调函数
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseData);

	// 设置请求头
	struct curl_slist* headers = nullptr;
	// 如果没有设置Content-Type，默认设置为application/json
	headers = curl_slist_append(headers, "Content-Type: application/json;charset=UTF-8");
	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

	// 设置超时时间(毫秒)
	curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, FtcSettings::connectTimeout());//连接超时时长
	curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, FtcSettings::requestTimeout());       //总超时时长

	// 执行请求
	const CURLcode res = curl_easy_perform(curl);

	// 获取HTTP状态码
	curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &m_httpCode);

	// 检查结果
	if (res != CURLE_OK)
	{
		m_error = "执行curl_easy_perform()失败: " + QString(curl_easy_strerror(res));
	}

	// 清理
	curl_easy_cleanup(curl);

	return res == CURLE_OK;
}
bool cxi_ftc::HttpClient::downloadFile(const QString& saveFileFullPath)
{
	if (m_url.isEmpty())
	{
		m_error = "未指定请求HTTP(S)地址。";
		return false;
	}

	// 创建curl句柄
	CURL* curl = curl_easy_init();
	if (!curl)
	{
		m_error = "创建curl句柄失败。";
		return false;
	}

	// 确保目录存在
	create_directories(std::filesystem::path(saveFileFullPath.toStdString()).parent_path());
	// 打开文件
	std::ofstream file(saveFileFullPath.toStdString(), std::ios::binary);
	if (!file.is_open())
	{
		m_error = "无法打开文件用于写入: " + saveFileFullPath;
		curl_easy_cleanup(curl);
		return false;
	}

	std::cout << "下载地址：" << m_url.toStdString() << ",保存路径：" << saveFileFullPath.toStdString() << std::endl;
	// 设置cURL选项
	curl_easy_setopt(curl, CURLOPT_URL, m_url.toStdString().c_str());
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeFileCallback);
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, &file);
	curl_easy_setopt(curl, CURLOPT_RESUME_FROM_LARGE, 0L);  // 禁用续传（从开头下载）
	//curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
	//curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progressCallback);
	//curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, m_impl);
	curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, FtcSettings::connectTimeout());
	curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, FtcSettings::requestTimeout());
	//curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); // 跟随重定向
	// 验证SSL证书（默认启用，提高安全性）
	curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
	//curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);

	// 执行下载
	const CURLcode res = curl_easy_perform(curl);

	// 获取HTTP状态码
	curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &m_httpCode);

	if (res != CURLE_OK)
	{
		m_error = "下载失败: " + QString(curl_easy_strerror(res));
		file.close();
		curl_easy_cleanup(curl);
		return false;
	}

	// // 获取文件总大小
	// double file_size = 0;
	// curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &file_size);

	if (m_httpCode != 200)
	{
		m_error = "HTTP错误: " + m_httpCode;
	}

	// 清理
	file.close();
	//curl_slist_free_all(headers);
	curl_easy_cleanup(curl);

	return res == CURLE_OK;
}
size_t cxi_ftc::HttpClient::writeCallback(void* ptr, const size_t size, size_t nMemb, std::string* userData)
{
	const size_t totalSize = size * nMemb;
	userData->append(static_cast<char*>(ptr), totalSize);
	return totalSize;
}
size_t cxi_ftc::HttpClient::writeFileCallback(const void* ptr, const size_t size, const size_t nmemb, void* userp)
{
	const auto file = static_cast<std::ofstream*>(userp);
	if (!file || !file->is_open())
	{
		return 0;
	}

	const size_t bytes = size * nmemb;
	file->write(static_cast<const char*>(ptr), bytes);
	return bytes;
}
int cxi_ftc::HttpClient::progressCallback(void* clientp, double dltotal, double dlnow, double ultotal, double ulnow)
{
	return 0; // 返回0继续传输，非0中止传输
}